package com.lx.video.web;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.lx.bean.Result;
import com.lx.bilibili.entity.UserAndVideo;
import com.lx.bilibili.entity.Video;
import com.lx.bilibili.entity.VideoEx;
import com.lx.bilibili.util.VideoRecommender;
import com.lx.video.dao.UserAndVideoMapper;
import com.lx.video.dao.VideoExMapper;
import com.lx.video.dao.VideoMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("video")
public class VideoController {
    private VideoExMapper videoExMapper;

    @Autowired
    public void setVideoExMapper(VideoExMapper videoExMapper) {
        this.videoExMapper = videoExMapper;
    }

    @Autowired
    VideoMapper videoMapper;

    @Autowired
    UserAndVideoMapper userAndVideoMapper;


    @Resource
    private RedisTemplate redisTemplate;

    @RequestMapping("recVideo")
    public List<VideoEx> recVideo(int page, int count){

        return videoExMapper.recVideo((page-1) * count, count);
    }


    @RequestMapping("getHotVideoByIdLimit")
    public List<Video> getHotVideoByIdLimit(int id, int page, int limit){
        return videoMapper.getHotVideoByIdLimit(id, (page - 1) * limit, limit );
    }

    @RequestMapping("getVideoByVid")
    public UserAndVideo getVideoByVid(int id){
        return userAndVideoMapper.getUserAndVideoById(id);
    }

    @RequestMapping("getRelVideo")
    public List<UserAndVideo> getRelVideo(int bid){
        return userAndVideoMapper.getRelVideo(bid);
    }

    @RequestMapping("getVcountByUid")
    public int getVcountByUid(int id){
        int vcountByUid = videoMapper.getVcountByUid(id);
        System.out.println("vcountByUid = " + vcountByUid);
        return vcountByUid;
    }

    @RequestMapping("getVideoByBid")
    public List<Video> getVideoByBid(int bid){
        LambdaQueryWrapper<Video> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Video::getBid, bid);
        return videoMapper.selectList(lqw);
    }

    @RequestMapping("playCount")
    public void playCount(String id) {
        // 使用正确的key前缀
        String redisKey = "video" + id;

        // 使用increment实现原子性递增
        redisTemplate.opsForValue().increment(redisKey, 1L);

        // 设置过期时间，避免长期占用内存（比如1小时过期）
        redisTemplate.expire(redisKey, 1, TimeUnit.HOURS);
    }



    @RequestMapping("getCollection")
    public List<Video> getCollection(int id, int page, int limit){
        return videoMapper.getCollection(id, (page - 1) * limit, limit);
    }

    @RequestMapping("getHotVideo")
    public Result getHotVideo(int page, int pageSize){
        List<VideoEx> hotVideos = videoExMapper.getHotVideo();
        redisTemplate.opsForValue().set("hotVideos", hotVideos);
        VideoRecommender videoRecommender = new VideoRecommender();
        List<VideoEx> videoOrder = videoRecommender.recommendVideos(hotVideos);
        if(hotVideos.size() < page * pageSize){
            return new Result(1, "success", videoOrder);
        }
        List<VideoEx> result = new ArrayList<>();
        for (int i = 0; i < page * pageSize ; i++) {
            result.add(videoOrder.get(i));
        }
        return new Result(1, "success", result);
    }

    @RequestMapping("getHotVideoByBoard")
    public Result getHotVideoByBoard(int bid){
        List<VideoEx> videos = (List<VideoEx>) redisTemplate.opsForValue().get("hotVideos");
        List<VideoEx> hotVideos = new ArrayList<>();
        for (VideoEx video : videos) {
            if(video.getBid().equals(bid)){
                hotVideos.add(video);
            }
        }
        return new Result(1, "success", hotVideos);
    }


    // ... existing code ...
    @Scheduled(fixedRate = 10000) // 3分钟 = 180000毫秒
    @Transactional
    public void scheduled() {
        Set<String> keys = redisTemplate.keys("video*");
        if (keys == null || keys.isEmpty()) {
            return;
        }

        for (String key : keys) {
            try {
                Long count = redisTemplate.opsForValue().increment(key, 0L); // 获取当前值
                if (count != null && count > 0) {
                    String videoId = key.replace("video", "");
                    videoMapper.update(null,
                            new LambdaUpdateWrapper<Video>()
                                    .eq(Video::getId, videoId)
                                    .setSql("vcount = vcount + " + count));
                    redisTemplate.delete(key);
                }
            } catch (Exception e) {
                System.err.println("更新视频播放量时出错，键: " + key + ", 错误信息: " + e.getMessage());
            }
        }
        System.out.println("视频播放量存入数据库");
    }

    // ... existing code ...
}
